package com.chaos.baofoo.http;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * 项目名称：baofoo-fopay-sdk-java
 * 类名称：表单参数
 * 类描述：
 * 创建人：陈少杰
 * 创建时间：2014-10-22 下午2:58:22
 * 修改人：陈少杰
 * 修改时间：2014-10-22 下午2:58:22
 */
public class SimpleHttpClient {

    private HttpClient httpclient;

    /**
     * 请求超时
     */
    private int connectionTimeout;

    /**
     * 读取超时
     */
    private int soTimeout;

    /**
     * 默认请求超时（单位：毫秒）
     */
    private static final int DEFAULT_CONNECTION_TIMEOUT = 30000;
    /**
     * 默认读取超时（单位：毫秒）
     */
    private static final int DEFAULT_SO_TIMEOUT = 90000;

    /**
     * 按默认请求超时，读取超时设置
     */
    public SimpleHttpClient() {
        this.connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
        this.soTimeout = DEFAULT_SO_TIMEOUT;

        this.httpclient = new DefaultHttpClient();

        this.httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout);
        this.httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, soTimeout);
    }

    /**
     * @param connectionTimeout 请求超时
     * @param soTimeout         读取超时
     */
    public SimpleHttpClient(int connectionTimeout, int soTimeout) {
        this.connectionTimeout = connectionTimeout;
        this.soTimeout = soTimeout;

        this.httpclient = new DefaultHttpClient();

        this.httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout);
        this.httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, soTimeout);
    }

    public void enableSSL() {

        try {
            // 创建信任所有证书的 X509TrustManager
            TrustManager tm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    // 不进行验证
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    // 不进行验证
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            };

            // 创建 SSLContext
            SSLContext sslContext = new SSLContextBuilder()
                    .loadTrustMaterial(null, (X509Certificate[] chain, String authType) -> true)
                    .build();

            // 创建 SSLConnectionSocketFactory
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslContext,
                    NoopHostnameVerifier.INSTANCE
            );

            // 创建 HttpClient
            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(100); // 整个连接池的最大连接数
            cm.setDefaultMaxPerRoute(10); // 每个路由的最大连接数

            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .setConnectionManager(cm)
                    .build();

            this.httpclient = httpClient;
        } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return the httpclient
     */
    public HttpClient getHttpclient() {
        return httpclient;
    }

    /**
     * @return the connectionTimeout
     */
    public int getConnectionTimeout() {
        return connectionTimeout;
    }

    /**
     * @param connectionTimeout the connectionTimeout to set
     */
    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
        this.httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout);
    }

    /**
     * @return the soTimeout
     */
    public int getSoTimeout() {
        return soTimeout;
    }

    /**
     * @param soTimeout the soTimeout to set
     */
    public void setSoTimeout(int soTimeout) {
        this.soTimeout = soTimeout;
        this.httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, soTimeout);
    }


}
